{
  "nbformat": 4,
  "nbformat_minor": 5,
  "metadata": {},
  "cells": [
    {
      "metadata": {},
      "source": [
        "<td>\n",
        "   <a target=\"_blank\" href=\"https://labelbox.com\" ><img src=\"https://labelbox.com/static/images/logo-v4.svg\" width=190/></a>\n",
        "</td>"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "<td>\n",
        "<a href=\"https://colab.research.google.com/github/Labelbox/labelbox-python/blob/master/examples/project_configuration/queue_management.ipynb\" target=\"_blank\"><img\n",
        "src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"></a>\n",
        "</td>\n",
        "\n",
        "<td>\n",
        "<a href=\"https://github.com/Labelbox/labelbox-python/tree/master/examples/project_configuration/queue_management.ipynb\" target=\"_blank\"><img\n",
        "src=\"https://img.shields.io/badge/GitHub-100000?logo=github&logoColor=white\" alt=\"GitHub\"></a>\n",
        "</td>"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "# Queue Management"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "* The queue is used to task labelers with specific assets\n",
        "* We can do any of the following:\n",
        "    * Set quality settings\n",
        "    * Set the order of items in the queue\n",
        "    * Set the percent of assets to review"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "!pip install labelbox -q\n",
        "!pip install numpy"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "import labelbox as lb\n",
        "from labelbox.schema.quality_mode import QualityMode\n",
        "from uuid import uuid4\n",
        "import json"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "# API Key and Client\n",
        "See the developer guide for [creating an API key](https://docs.labelbox.com/reference/create-api-key)."
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "# Add your API key\n",
        "API_KEY = \"\"\n",
        "client = lb.Client(api_key=API_KEY)"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "### Set up demo project"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "#### Create project"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "# Create Labelbox  project\n",
        "\n",
        "project = client.create_project(name=\"batch-test-project\",\n",
        "                                description=\"a description\",\n",
        "                                quality_mode=QualityMode.Benchmark, # For Consensus projects use quality_mode = QualityMode.Consensus\n",
        "                                media_type=lb.MediaType.Image,\n",
        "                                )\n",
        "\n",
        "dataset = client.create_dataset(name=\"queue_dataset\")"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "#### Create ontology and attach to project"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "classification_features = [\n",
        "    lb.Classification(\n",
        "        class_type=lb.Classification.Type.CHECKLIST,\n",
        "        name=\"Quality Issues\",\n",
        "        options=[\n",
        "            lb.Option(value=\"blurry\", label=\"Blurry\"),\n",
        "            lb.Option(value=\"distorted\", label=\"Distorted\")\n",
        "        ]\n",
        "    )\n",
        "]\n",
        "\n",
        "ontology_builder = lb.OntologyBuilder(\n",
        "    tools=[],\n",
        "    classifications=classification_features\n",
        ")\n",
        "\n",
        "ontology = client.create_ontology(\n",
        "  \"Ontology from new features\",\n",
        "  ontology_builder.asdict(),\n",
        "  media_type=lb.MediaType.Image\n",
        ")\n",
        "\n",
        "project.setup_editor(ontology)"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "# Add data to your dataset"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "## Example image\n",
        "uploads = []\n",
        "global_keys = []\n",
        "# Generate data rows\n",
        "for i in range(1, 5):\n",
        "  global_key = str(uuid4())\n",
        "  row = {\n",
        "      \"row_data\":  f\"https://storage.googleapis.com/labelbox-datasets/People_Clothing_Segmentation/jpeg_images/IMAGES/img_000{i}.jpeg\",\n",
        "      \"global_key\": global_key\n",
        "    }\n",
        "  global_keys.append(global_key)\n",
        "  uploads.append(row)\n",
        "\n",
        "\n",
        "data_rows = dataset.create_data_rows(uploads)\n",
        "data_rows.wait_till_done()\n",
        "print(\"Errors\" , data_rows.errors)\n",
        "print(\"Dataset status: \", data_rows.status)\n"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "# Attach data to your project and set data row priority"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "######## Create batches \n",
        "\n",
        "# Create the batch \n",
        "\n",
        "batch = project.create_batch(\n",
        "  \"batch-demo\", # Each batch in a project must have a unique name\n",
        "  global_keys = global_keys[0:2], # A list of data rows, data row ids or global keys\n",
        "  priority=5 # priority between 1(Highest) - 5(lowest) 5 is the max priority that can be set\n",
        ")\n",
        "\n",
        "batch2 = project.create_batch(\n",
        "  \"batch-demo-2\", # Each batch in a project must have a unique name\n",
        "  #Provide a slice of the data since you can't import assets with global keys that already exist in the project.\n",
        "  global_keys=global_keys[2:4], # A list of data rows, data row ids or global keys\n",
        "  priority=1 # priority between 1(Highest) - 5(lowest) 5 is the max priority that can be set\n",
        ")\n",
        "\n",
        "\n",
        "print(\"Batch: \", batch)\n",
        "print(\"Batch2: \", batch2)"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "print(\"View the results here:\",\n",
        "      f\"https://app.labelbox.com/projects/{project.uid}\")\n",
        "# Click `start labeling` to see the images in order"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "## Queue Order\n",
        "- Add priority for each data row\n",
        "- Update priority for each data row"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "client.enable_experimental = True\n",
        "\n",
        "export_task = project.export()\n",
        "export_task.wait_till_done()"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "# Get data rows from project\n",
        "data_rows = []\n",
        "\n",
        "def json_stream_handler(output: lb.JsonConverterOutput):\n",
        "  data_row = json.loads(output.json_str)\n",
        "  data_rows.append(lb.GlobalKey(data_row[\"data_row\"][\"global_key\"])) # Convert json data row into data row identifier object\n",
        "\n",
        "\n",
        "if export_task.has_errors():\n",
        "  export_task.get_stream(\n",
        "  \n",
        "  converter=lb.JsonConverter(),\n",
        "  stream_type=lb.StreamType.ERRORS\n",
        "  ).start(stream_handler=lambda error: print(error))\n",
        "\n",
        "if export_task.has_result():\n",
        "  export_json = export_task.get_stream(\n",
        "    converter=lb.JsonConverter(),\n",
        "    stream_type=lb.StreamType.RESULT\n",
        "  ).start(stream_handler=json_stream_handler)"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "# Get label parameter overrides (LPOs)\n",
        "project_lpos = project.labeling_parameter_overrides()\n",
        "\n",
        "for lpo in project_lpos:\n",
        "  print(lpo)\n",
        "  print(\"Data row:\", lpo.data_row().uid)"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "# Add LPOs\n",
        "lpos = []\n",
        "priority=1\n",
        "for data_row in data_rows: \n",
        "  lpos.append((data_row, priority, 1))\n",
        "  priority+=1\n",
        "\n",
        "\n",
        "project.set_labeling_parameter_overrides(lpos)\n",
        "\n",
        "# Check results\n",
        "project_lpos = list(project.labeling_parameter_overrides())\n",
        "\n",
        "for lpo in project_lpos:\n",
        "  print(lpo)"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "# Update LPOs\n",
        "global_keys = []\n",
        "for data_row in data_rows:\n",
        "    global_keys.append(data_row.key)\n",
        "\n",
        "project.update_data_row_labeling_priority(data_rows=lb.GlobalKeys(global_keys), priority=1)\n",
        "\n",
        "# Check results\n",
        "project_lpos = list(project.labeling_parameter_overrides())\n",
        "\n",
        "for lpo in project_lpos:\n",
        "  print(lpo)"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {},
      "source": [
        "# Cleanup"
      ],
      "cell_type": "markdown"
    },
    {
      "metadata": {},
      "source": [
        "# project.delete()\n",
        "# dataset.delete()"
      ],
      "cell_type": "code",
      "outputs": [],
      "execution_count": null
    }
  ]
}